Function.prototype.call2 = function (context) {
    // context 如果是 null、undefined 或其他 falsy 值时，赋予原生 call 函数一样的表现形式
    function getContext(target) {
        return (target === null || target === undefined) ? window : Object.create(null)
    }

    context = context || getContext(context);
    // 此处的 this 值是 call2 的调用者，也是一个函数
    context.fn = this;

    let args = [];
    for (let i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
    // args => [ 'arguments[1]', 'arguments[2]' ]
    // arguments[1] => 1
    // arguments[2] => 2

    let result = eval('context.fn(' + args + ')');
    // 'hello' +  [' world'] + '!'  => hello world!
    // 'context.fn(' + args + ')'   =>  context.fn(arguments[1],arguments[2])
    // 使用 eval函数 执行 context.fn(arguments[1],arguments[2]) 字符串

    delete context.fn
    // result => 666，将执行后的函数的返回值 result 返回
    return result;
}


// const obj = {
//     foo: 'foo',
//     say: function (a, b) {
//         console.log(this.foo, a, b);
//         return 666
//     }
// }
//
// const obj2 = {
//     foo: 'bar'
// }
//
// obj.say.call2(obj2, 1, 2)  // bar 1 2
